using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 火爆辣椒攻击策略 - 对整行僵尸造成伤害
/// </summary>
public class JalapenoAttackStrategy : AttackStrategyBase
{
    private Coroutine m_AttackCoroutine;
    private JalapenoSkillData m_JalapenoData;
    private GameObject m_EffectInstance; // 特效实例

    public JalapenoAttackStrategy(SkillData data)
    {
        AttackData = data;
        if (data is JalapenoSkillData jalapenoData)
        {
            m_JalapenoData = jalapenoData;
        }
    }

    public override void Execute(Entity target)
    {
        base.Execute(target);

        if (Owner == null)
        {
            Logger.LogWarning("JalapenoAttackStrategy", "Owner为空，无法执行攻击");
            return;
        }

        // 启动攻击协程
        if (m_AttackCoroutine == null)
        {
            m_AttackCoroutine = Owner.StartCoroutine(AttackRoutine());
        }
    }

    /// <summary>
    /// 攻击协程
    /// </summary>
    private IEnumerator AttackRoutine()
    {
        if (m_JalapenoData == null)
        {
            Logger.LogWarning("JalapenoAttackStrategy", "JalapenoSkillData为空");
            yield break;
        }

        // 等待触发延迟
        yield return new WaitForSeconds(m_JalapenoData.TriggerDelay);

        // 创建并播放特效
        CreateEffect();

        // 获取植物所在的Cell
        Cell cell = GetPlantCell();
        if (cell == null)
        {
            Logger.LogWarning("JalapenoAttackStrategy", "无法获取植物所在的Cell");
            yield break;
        }

        // 查找同一行的所有僵尸
        List<Zombie> zombiesInRow = FindZombiesInRow(cell.Row);
        
        // 对整行僵尸造成爆炸伤害
        foreach (var zombie in zombiesInRow)
        {
            if (zombie != null && !zombie.HealthComponent.IsDead)
            {
                // 造成爆炸伤害
                long damage = m_JalapenoData.ExplosionDamage;
                zombie.HealthComponent.TakeDamage(damage);
                Logger.Log("JalapenoAttackStrategy", $"{Owner.name} 对 {zombie.name} 造成 {damage} 点爆炸伤害");
                
                // 如果技能数据有Effects列表，执行效果
                if (AttackData != null && AttackData.Effects != null && AttackData.Effects.Count > 0)
                {
                    SkillExecutor.Execute(AttackData.Effects, Owner, zombie);
                }
            }
        }

        // 如果设置了持续火焰伤害，启动持续伤害协程
        // 注意：植物死亡后，协程可能无法继续执行，所以持续伤害应该在植物死亡前启动
        if (m_JalapenoData.FireDuration > 0 && m_JalapenoData.FireDamagePerSecond > 0)
        {
            Owner.StartCoroutine(FireDamageRoutine(zombiesInRow));
        }

        // 如果是一次性使用，等待一小段时间后杀死植物
        // 等待时间让伤害和特效有时间显示
        if (m_JalapenoData.IsOneTimeUse && Owner != null)
        {
            // 等待一小段时间，确保伤害已应用，特效开始播放
            yield return new WaitForSeconds(0.2f);
            
            // 杀死植物
            if (Owner != null && Owner.HealthComponent != null && !Owner.HealthComponent.IsDead)
            {
                // 直接造成足够杀死植物的伤害
                long currentHealth = Owner.HealthComponent.CurHealth;
                Owner.HealthComponent.TakeDamage(currentHealth);
                Logger.Log("JalapenoAttackStrategy", $"{Owner.name} 触发攻击后死亡");
                
                // 触发死亡状态（HealthComponent会自动触发，但为了确保，我们也可以手动触发）
                if (Owner.FSMComponent != null && Owner.HealthComponent.IsDead)
                {
                    Owner.FSMComponent.ChangeStatus(FSMType.Dead);
                }
            }
        }

        // 启动独立的协程等待特效播放完成并销毁
        // 注意：这个协程在特效对象上运行，不依赖于Owner，即使植物死亡也能继续执行
        if (m_EffectInstance != null)
        {
            // 保存特效实例的引用，用于Cancel时销毁
            GameObject effectInstance = m_EffectInstance;
            
            // 在特效对象上启动协程，等待动画播放完成后销毁
            StartCoroutineOnEffect(WaitForEffectAndDestroy(effectInstance, () => {
                // 回调函数：当特效销毁后，清除引用
                if (m_EffectInstance == effectInstance)
                {
                    m_EffectInstance = null;
                }
            }));
        }

        m_AttackCoroutine = null;
    }

    /// <summary>
    /// 持续火焰伤害协程
    /// </summary>
    private IEnumerator FireDamageRoutine(List<Zombie> zombies)
    {
        float elapsed = 0f;
        float damageInterval = 1f; // 每秒造成一次伤害
        float nextDamageTime = 0f;

        while (elapsed < m_JalapenoData.FireDuration && zombies != null && zombies.Count > 0)
        {
            elapsed += Time.deltaTime;

            if (elapsed >= nextDamageTime)
            {
                // 移除已死亡的僵尸
                zombies.RemoveAll(z => z == null || z.HealthComponent.IsDead);

                // 对存活的僵尸造成火焰伤害
                foreach (var zombie in zombies)
                {
                    if (zombie != null && !zombie.HealthComponent.IsDead)
                    {
                        zombie.HealthComponent.TakeDamage(m_JalapenoData.FireDamagePerSecond);
                        Logger.Log("JalapenoAttackStrategy", $"{Owner.name} 对 {zombie.name} 造成 {m_JalapenoData.FireDamagePerSecond} 点持续火焰伤害");
                    }
                }

                nextDamageTime = elapsed + damageInterval;
            }

            yield return null;
        }
    }

    /// <summary>
    /// 获取植物所在的Cell
    /// </summary>
    private Cell GetPlantCell()
    {
        if (Owner == null) return null;

        // 植物是Cell的子对象，通过父对象获取Cell组件
        Transform parent = Owner.transform.parent;
        if (parent != null)
        {
            Cell cell = parent.GetComponent<Cell>();
            if (cell != null)
            {
                return cell;
            }
        }

        // 如果父对象没有Cell组件，尝试在场景中查找
        // 通过位置查找最近的Cell
        Cell[] allCells = UnityEngine.Object.FindObjectsOfType<Cell>();
        Cell nearestCell = null;
        float nearestDistance = float.MaxValue;

        foreach (var cell in allCells)
        {
            float distance = Vector3.Distance(Owner.transform.position, cell.transform.position);
            if (distance < nearestDistance)
            {
                nearestDistance = distance;
                nearestCell = cell;
            }
        }

        return nearestCell;
    }

    /// <summary>
    /// 查找指定行的所有僵尸
    /// </summary>
    private List<Zombie> FindZombiesInRow(int row)
    {
        List<Zombie> zombiesInRow = new List<Zombie>();

        // 使用EntityService查找所有实体
        var entityService = ServiceManager.Instance.GetService<EntityService>();
        if (entityService != null)
        {
            var allEntities = entityService.GetAllEntities();
            foreach (var entity in allEntities)
            {
                if (entity is Zombie zombie && !zombie.HealthComponent.IsDead)
                {
                    // 检查僵尸是否在同一行
                    if (IsZombieInRow(zombie, row))
                    {
                        zombiesInRow.Add(zombie);
                    }
                }
            }
        }
        else
        {
            // 降级方案：使用FindObjectsOfType
            Zombie[] allZombies = UnityEngine.Object.FindObjectsOfType<Zombie>();
            foreach (var zombie in allZombies)
            {
                if (!zombie.HealthComponent.IsDead && IsZombieInRow(zombie, row))
                {
                    zombiesInRow.Add(zombie);
                }
            }
        }

        Logger.Log("JalapenoAttackStrategy", $"在第 {row} 行找到 {zombiesInRow.Count} 个僵尸");
        return zombiesInRow;
    }

    /// <summary>
    /// 检查僵尸是否在指定行
    /// </summary>
    private bool IsZombieInRow(Zombie zombie, int targetRow)
    {
        if (zombie == null) return false;

        // 方法1：找到僵尸最近的Cell（所有行），如果这个Cell的行号等于目标行，则僵尸在该行
        // 这是最准确的方法，因为可以确保僵尸真的在目标行的某个Cell附近
        Cell[] allCells = UnityEngine.Object.FindObjectsOfType<Cell>();
        if (allCells == null || allCells.Length == 0) return false;

        Cell nearestCell = null;
        float nearestDistance = float.MaxValue;

        // 查找所有Cell中距离僵尸最近的（不限制行）
        foreach (var cell in allCells)
        {
            if (cell == null) continue;
            
            float distance = Vector3.Distance(zombie.transform.position, cell.transform.position);
            if (distance < nearestDistance)
            {
                nearestDistance = distance;
                nearestCell = cell;
            }
        }

        // 如果最近的Cell在目标行，且距离在合理范围内（比如1.5个单位，大约是Cell的一半宽度）
        // 这样可以确保僵尸真的在目标行的格子范围内
        if (nearestCell != null && nearestCell.Row == targetRow && nearestDistance < 1.5f)
        {
            Logger.Log("JalapenoAttackStrategy", $"僵尸 {zombie.name} 在第 {targetRow} 行（最近Cell: Row={nearestCell.Row}, Col={nearestCell.Column}, 距离={nearestDistance:F2}）");
            return true;
        }

        // 方法2：通过Y坐标判断（备用方法，但更严格）
        // 获取目标行的所有Cell，计算Y坐标范围
        float minY = float.MaxValue;
        float maxY = float.MinValue;
        int cellCount = 0;
        
        foreach (var cell in allCells)
        {
            if (cell != null && cell.Row == targetRow)
            {
                float cellY = cell.transform.position.y;
                if (cellY < minY) minY = cellY;
                if (cellY > maxY) maxY = cellY;
                cellCount++;
            }
        }

        if (cellCount > 0)
        {
            // 计算Y坐标容差（Cell高度的一半，假设Cell高度约为1单位）
            float yTolerance = 0.3f;
            float zombieY = zombie.transform.position.y;
            
            // 僵尸的Y坐标必须在目标行的Y坐标范围内（加上容差）
            if (zombieY >= minY - yTolerance && zombieY <= maxY + yTolerance)
            {
                // 进一步检查：僵尸必须距离目标行的某个Cell足够近
                // 这样可以避免其他行的僵尸因为Y坐标接近而被误判
                foreach (var cell in allCells)
                {
                    if (cell != null && cell.Row == targetRow)
                    {
                        float distance = Vector3.Distance(zombie.transform.position, cell.transform.position);
                        if (distance < 1.5f)
                        {
                            Logger.Log("JalapenoAttackStrategy", $"僵尸 {zombie.name} 在第 {targetRow} 行（Y坐标匹配，距离Cell Row={cell.Row}, Col={cell.Column} 为 {distance:F2}）");
                            return true;
                        }
                    }
                }
            }
        }

        Logger.Log("JalapenoAttackStrategy", $"僵尸 {zombie.name} 不在第 {targetRow} 行（最近Cell: Row={nearestCell?.Row ?? -1}, 距离={nearestDistance:F2}）");
        return false;
    }

    /// <summary>
    /// 创建特效
    /// </summary>
    private void CreateEffect()
    {
        if (AttackData == null || AttackData.Prefab == null)
        {
            Logger.LogWarning("JalapenoAttackStrategy", "技能数据中没有特效Prefab");
            return;
        }

        if (Owner == null)
        {
            Logger.LogWarning("JalapenoAttackStrategy", "Owner为空，无法创建特效");
            return;
        }

        // 获取植物所在的Cell，用于确定特效位置
        Cell plantCell = GetPlantCell();
        Vector3 effectPosition = Owner.transform.position + AttackData.PrefabOffset;
        
        if (plantCell != null)
        {
            // 计算当前行的中心位置
            effectPosition = GetRowCenterPosition(plantCell.Row);
            if (effectPosition == Vector3.zero)
            {
                // 如果计算失败，使用植物所在Cell的位置作为备用
                effectPosition = plantCell.transform.position;
            }
            // 应用偏移
            effectPosition += AttackData.PrefabOffset;
        }

        // 实例化特效
        m_EffectInstance = GameObject.Instantiate(AttackData.Prefab, effectPosition, Quaternion.identity);
        
        // 如果特效有Animator组件，确保它开始播放
        Animator effectAnimator = m_EffectInstance.GetComponent<Animator>();
        if (effectAnimator != null)
        {
            effectAnimator.enabled = true;
            // 可以触发特定的动画触发器
            effectAnimator.SetTrigger("Play");
        }

        // 如果特效有ParticleSystem组件，确保它开始播放
        ParticleSystem[] particleSystems = m_EffectInstance.GetComponentsInChildren<ParticleSystem>();
        foreach (var ps in particleSystems)
        {
            if (ps != null)
            {
                ps.Play();
            }
        }

        // 如果特效有Animation组件，确保它开始播放
        Animation effectAnimation = m_EffectInstance.GetComponent<Animation>();
        if (effectAnimation != null)
        {
            effectAnimation.Play();
        }

        Logger.Log("JalapenoAttackStrategy", $"创建特效: {AttackData.Prefab.name} 在位置 {effectPosition}");
    }

    /// <summary>
    /// 获取指定行的中心位置
    /// </summary>
    /// <param name="row">行号</param>
    /// <returns>行的中心位置，如果找不到Cell则返回Vector3.zero</returns>
    private Vector3 GetRowCenterPosition(int row)
    {
        // 查找场景中所有的Cell
        Cell[] allCells = UnityEngine.Object.FindObjectsOfType<Cell>();
        if (allCells == null || allCells.Length == 0)
        {
            Logger.LogWarning("JalapenoAttackStrategy", $"找不到任何Cell，无法计算第 {row} 行的中心位置");
            return Vector3.zero;
        }

        // 收集指定行的所有Cell
        List<Cell> cellsInRow = new List<Cell>();
        foreach (var cell in allCells)
        {
            if (cell != null && cell.Row == row)
            {
                cellsInRow.Add(cell);
            }
        }

        if (cellsInRow.Count == 0)
        {
            Logger.LogWarning("JalapenoAttackStrategy", $"找不到第 {row} 行的任何Cell");
            return Vector3.zero;
        }

        // 计算所有Cell位置的平均值（中心位置）
        Vector3 centerPosition = Vector3.zero;
        foreach (var cell in cellsInRow)
        {
            centerPosition += cell.transform.position;
        }
        centerPosition /= cellsInRow.Count;

        Logger.Log("JalapenoAttackStrategy", $"第 {row} 行有 {cellsInRow.Count} 个Cell，中心位置: {centerPosition}");
        return centerPosition;
    }

    /// <summary>
    /// 等待特效播放完成后销毁
    /// </summary>
    private IEnumerator WaitForEffectAndDestroy(GameObject effectInstance, System.Action onDestroyed = null)
    {
        if (effectInstance == null)
        {
            onDestroyed?.Invoke();
            yield break;
        }

        // 等待几帧，确保动画/粒子系统已经开始播放
        yield return null;
        yield return null;

        // 获取特效的动画和粒子系统信息
        Animator effectAnimator = effectInstance.GetComponent<Animator>();
        Animation effectAnimation = effectInstance.GetComponent<Animation>();
        ParticleSystem[] particleSystems = effectInstance.GetComponentsInChildren<ParticleSystem>();

        float maxDuration = 0f;

        // 检查Animator动画
        if (effectAnimator != null && effectAnimator.enabled)
        {
            AnimatorStateInfo stateInfo = effectAnimator.GetCurrentAnimatorStateInfo(0);
            if (stateInfo.length > 0)
            {
                maxDuration = Mathf.Max(maxDuration, stateInfo.length);
                Logger.Log("JalapenoAttackStrategy", $"特效Animator动画长度: {stateInfo.length}秒");
            }
        }

        // 检查Animation组件
        if (effectAnimation != null && effectAnimation.clip != null)
        {
            float clipLength = effectAnimation.clip.length;
            if (clipLength > 0)
            {
                maxDuration = Mathf.Max(maxDuration, clipLength);
                Logger.Log("JalapenoAttackStrategy", $"特效Animation动画长度: {clipLength}秒");
            }
        }

        // 检查粒子系统
        if (particleSystems != null && particleSystems.Length > 0)
        {
            foreach (var ps in particleSystems)
            {
                if (ps != null && ps.main.duration > 0)
                {
                    // 粒子系统持续时间 = main.duration + main.startLifetime（考虑粒子的生命周期）
                    float psDuration = ps.main.duration + ps.main.startLifetime.constantMax;
                    maxDuration = Mathf.Max(maxDuration, psDuration);
                    Logger.Log("JalapenoAttackStrategy", $"特效粒子系统持续时间: {psDuration}秒");
                }
            }
        }

        // 如果无法获取动画/粒子系统信息，使用AttackData.Duration或默认值
        if (maxDuration <= 0)
        {
            maxDuration = AttackData?.Duration > 0 ? AttackData.Duration : 2f;
            Logger.LogWarning("JalapenoAttackStrategy", $"无法获取特效播放时长，使用默认值: {maxDuration}秒");
        }

        // 等待特效播放完成
        float elapsedTime = 0f;
        float maxWaitTime = maxDuration * 1.5f; // 多等待50%的时间，确保特效完全播放完成

        while (elapsedTime < maxWaitTime && effectInstance != null)
        {
            // 检查Animator动画是否播放完成
            if (effectAnimator != null && effectAnimator.enabled)
            {
                AnimatorStateInfo stateInfo = effectAnimator.GetCurrentAnimatorStateInfo(0);
                if (stateInfo.normalizedTime >= 1f)
                {
                    Logger.Log("JalapenoAttackStrategy", "特效Animator动画播放完成");
                    break;
                }
            }

            // 检查Animation是否播放完成
            if (effectAnimation != null && effectAnimation.isPlaying)
            {
                // Animation还在播放，继续等待
            }
            else if (effectAnimation != null && !effectAnimation.isPlaying)
            {
                // Animation已停止播放
                Logger.Log("JalapenoAttackStrategy", "特效Animation动画播放完成");
                // 继续检查粒子系统
            }

            // 检查粒子系统是否还在播放
            bool anyParticlePlaying = false;
            if (particleSystems != null && particleSystems.Length > 0)
            {
                foreach (var ps in particleSystems)
                {
                    if (ps != null && ps.isPlaying)
                    {
                        anyParticlePlaying = true;
                        break;
                    }
                }
            }

            // 如果动画和粒子系统都完成了，可以提前退出
            bool animatorFinished = true;
            if (effectAnimator != null && effectAnimator.enabled)
            {
                AnimatorStateInfo stateInfo = effectAnimator.GetCurrentAnimatorStateInfo(0);
                animatorFinished = stateInfo.normalizedTime >= 1f;
            }
            
            bool animationFinished = effectAnimation == null || !effectAnimation.isPlaying;
            
            if (animatorFinished && animationFinished && !anyParticlePlaying)
            {
                Logger.Log("JalapenoAttackStrategy", "特效所有动画和粒子系统都播放完成");
                break;
            }

            elapsedTime += Time.deltaTime;
            yield return null;
        }

        // 销毁特效
        DestroyEffectInstance(effectInstance);
        
        // 调用回调，清除引用
        onDestroyed?.Invoke();
    }

    /// <summary>
    /// 销毁特效实例（静态方法，不依赖成员变量）
    /// </summary>
    private void DestroyEffectInstance(GameObject effectInstance)
    {
        if (effectInstance == null) return;

        // 停止粒子系统
        ParticleSystem[] particleSystems = effectInstance.GetComponentsInChildren<ParticleSystem>();
        foreach (var ps in particleSystems)
        {
            if (ps != null)
            {
                ps.Stop();
            }
        }

        // 销毁特效对象
        GameObject.Destroy(effectInstance);
        Logger.Log("JalapenoAttackStrategy", "特效已销毁");
    }

    /// <summary>
    /// 在特效对象上启动协程（如果特效对象有MonoBehaviour组件）
    /// 如果没有，则在Owner上启动（如果Owner还存在）
    /// </summary>
    private void StartCoroutineOnEffect(IEnumerator coroutine)
    {
        if (m_EffectInstance == null) return;

        // 尝试在特效对象上添加一个临时组件来运行协程
        MonoBehaviour effectMono = m_EffectInstance.GetComponent<MonoBehaviour>();
        if (effectMono == null)
        {
            // 如果特效对象没有MonoBehaviour组件，添加一个临时组件
            effectMono = m_EffectInstance.AddComponent<EffectLifecycleManager>();
        }

        if (effectMono != null)
        {
            effectMono.StartCoroutine(coroutine);
            Logger.Log("JalapenoAttackStrategy", "在特效对象上启动销毁协程");
        }
        else if (Owner != null)
        {
            // 降级方案：在Owner上启动协程
            Owner.StartCoroutine(coroutine);
            Logger.Log("JalapenoAttackStrategy", "在Owner上启动销毁协程（降级方案）");
        }
        else
        {
            Logger.LogWarning("JalapenoAttackStrategy", "无法启动特效销毁协程，特效可能不会被自动销毁");
        }
    }

    /// <summary>
    /// 销毁特效（使用成员变量）
    /// </summary>
    private void DestroyEffect()
    {
        if (m_EffectInstance != null)
        {
            DestroyEffectInstance(m_EffectInstance);
            m_EffectInstance = null;
        }
    }

    public override void Cancel()
    {
        if (m_AttackCoroutine != null && Owner != null)
        {
            Owner.StopCoroutine(m_AttackCoroutine);
            m_AttackCoroutine = null;
        }

        // 取消时也要销毁特效
        DestroyEffect();
    }
}

